home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / New System Software Extensions / Thread Manager Extension 2.0.1 / Sample Applications / Power Examples / SortPicts / Source / GWorldObj.cp < prev    next >
Encoding:
Text File  |  1994-06-03  |  34.4 KB  |  1,505 lines  |  [TEXT/MPS ]

  1. /*************************************************************************************
  2.  *
  3.  *    Create an Offscreen GWorld, Randomize and Sort it
  4.  *
  5.  *    GWorld.cp    -    C Source
  6.  *
  7.  *      Copyright © Apple Computer, Inc. 1988 - 1993
  8.  *      All rights reserved.
  9.  *
  10.  *    This is the "meat" of the SortPicts program.  This file supplies the
  11.  *      core functionality to SortPicts by overiding and supplementing
  12.  *      the WindowObj class.  
  13.  *
  14.  *************************************************************************************/
  15.  
  16. #include "GWorldObj.h"
  17. #include <stdio.h>
  18.  
  19. Boolean        gSetWTitleOK;        //    This is program wide so that DragHook can get to it!
  20.                                 //    Is it OK to set the Title?  False during DragWindow!!
  21. pascal    Boolean        AboutBoxFilter( DialogPtr dialog, EventRecord *event, short *itemHit);
  22.  
  23. #ifndef __powerc
  24. pascal    void        DragHookForThreads( void);
  25. #endif
  26.  
  27. pascal    void       *GWorldThreadEntry( void *there);
  28.  
  29. pascal void            XDrawDragRgn( void);
  30. RgnHandle            gDragRgnHandle;    //    You wouldn't believe me if I told you... but Watch this guy!
  31. GrafPtr                gDragPort;        //    These are used to Hide and Show the Drag Rgn
  32. PenState            gDragPen;        //    Just before a CopyBits action!!  (Can you believe how skanky that is??)
  33. Boolean                gDragRgnHandleValid;    //    Is the DragRgnHandle really a drag RgnHandle?
  34.     
  35. #ifndef __powerc
  36. RgnHandle            ReturnA3( void) = {0x204B, 0x200B};
  37. //                        = 0x200B;            //    MOVE.L    A3,D0
  38. //                        & 0x204B            //  MOVE.L    A3,A0     -- support for Metro•Werks
  39. #endif
  40.  
  41.  
  42. Boolean    GWorldObj::BeginNewThread( void)
  43. {
  44.     OSErr            errWhatErr;
  45.     
  46.     
  47.     if( gHasThreads)
  48.     {
  49.         errWhatErr = NewThread( kCooperativeThread, 
  50.                                 GWorldThreadEntry, 
  51.                                 (void *)this, 
  52.                                 100000,
  53.                                 kFPUNotNeeded + kCreateIfNeeded,
  54.                                 (void**)nil,
  55.                                 &threadInfo);
  56.         
  57.         if( errWhatErr != noErr)
  58.             return false;
  59.         else
  60.             return true;        //  Successful new thread running!!
  61.     }
  62. }
  63.  
  64.  
  65. pascal    void   *GWorldThreadEntry( void *there)        // it's really "this" here
  66. {
  67.     GWorldObj           *object = (GWorldObj *)there;
  68.  
  69.     object->doneSorting = false;
  70.     object->ScramblePict();
  71.  
  72.     switch( object->gSortAlgorithm)
  73.     {
  74.         case iShellSort:
  75.             object->ShellSort();
  76.             break;
  77.         case iHeapSort:
  78.             object->HeapSort();
  79.             break;
  80.         case iQuickSort:
  81.             object->QuickSort();
  82.             break;
  83.  
  84.         case iRandomSort:
  85.             switch( object->RandomPixel(3) +1)
  86.             {
  87.                 case iShellSort:
  88.                     object->ShellSort();
  89.                     break;
  90.                 case iHeapSort:
  91.                     object->HeapSort();
  92.                     break;
  93.                 case iQuickSort:
  94.                     object->QuickSort();
  95.                     break;
  96.             }
  97.         default:
  98.             object->QuickSort();
  99.     }
  100.  
  101.     object->threadInfo = 0;
  102.     return nil;
  103. }
  104.  
  105.  
  106. /*************************************************************/
  107. /*                                                           */
  108. /*               A Sort and Draw Help Routine                */
  109. /*                                                           */
  110. /*************************************************************/
  111. void    GWorldObj::SetSortItem( long index, long data)
  112. {
  113.     long                horiz, vert;
  114.     
  115.     horiz = index % pictWidth;
  116.     vert = index / pictWidth;
  117.     
  118.     copyBitsRect.left = 0;
  119.     copyBitsRect.right = pictWidth;
  120.     
  121.     if( vert >= copyBitsRect.bottom)
  122.         copyBitsRect.bottom = (short) vert+1;
  123.  
  124.     if( vert < copyBitsRect.top)
  125.         copyBitsRect.top = (short) vert;
  126.  
  127.     sortListPtr[index] = data;
  128.     offset = horiz + (vert * pictRowBytes);
  129.     offscreenPtr[offset] = (Byte)data;
  130. }
  131.  
  132. void    GWorldObj::ExchangeSortItem( long one, long theOther)
  133. {
  134.     long        temp;
  135.     
  136.     temp = sortListPtr[one];
  137.     SetSortItem( one, sortListPtr[theOther]);
  138.     SetSortItem( theOther, temp);
  139. }
  140.  
  141.  
  142. OSErr    GWorldObj::YieldIfTime( char *mmuMode)
  143. {
  144.     EventRecord        tempEvent;
  145.     long            *tickPtr = (long *)0x16A;
  146.  
  147.     if( !yieldTime)
  148.     {
  149.         yieldTime = *tickPtr + gYieldDelay;
  150.         return noErr;
  151.     }
  152.     
  153.     if( *tickPtr >= yieldTime )
  154.     {
  155. #ifndef DEMO
  156.         UnuseGWorld();
  157.         SwapMMUMode( mmuMode);
  158.         
  159.         SetPort( me);
  160.         DrawObj();
  161.  
  162. #endif
  163.         if( gHasThreads == true) 
  164.             if( yieldOnlyToMe == false)
  165.                 YieldToAnyThread();
  166.             else
  167.                 YieldToThread( kApplicationThreadID);
  168.         else        //    No Threads package
  169.             if( EventAvail( mDownMask + keyDownMask, &tempEvent) == true)
  170.             {
  171.                 if( tempEvent.what == mouseDown)
  172.                     GetNextEvent( mDownMask + keyDownMask, &tempEvent);
  173.                 return memLockedErr;
  174.             }
  175.  
  176.         SwapMMUMode( mmuMode);
  177.         UseGWorld();
  178.  
  179. #ifdef DEMO
  180.         //    f->osPixmap = ((CWindowPtr)me)->portPixMap;
  181.         //    f->pixels = (unsigned char *) GetPixBaseAddr( f->osPixmap);
  182.         //    f->osRowBytes = (**(f->osPixmap)).rowBytes & 0x3FFF;
  183.         //    f->pixels -= (long) ((**(f->osPixmap)).bounds.top * f->osRowBytes) + (**(f->osPixmap)).bounds.left;
  184.         offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
  185.                         (**(((CWindowPtr)me)->portPixMap)).bounds.left;
  186. #endif
  187.         yieldTime = *tickPtr + gYieldDelay;
  188.     }
  189.     return noErr;
  190. }
  191.  
  192.  
  193. void    GWorldObj::UpdateObj( void)
  194. {
  195.     Rect        tempRect = copyBitsRect;
  196.     Rect        windowRect = windPictRect;
  197.     
  198.     copyBitsRect = worldPictRect;
  199.     DrawObj();
  200.     copyBitsRect = tempRect;
  201. }
  202.  
  203. void    GWorldObj::DrawObj( void)
  204. {
  205.     Rect        worldRect = copyBitsRect;
  206.     Rect        windowRect = windPictRect;
  207.     
  208. #ifdef DEMO
  209.     ValidRect( &windowRect);
  210.     return;
  211. #endif
  212.     
  213.     XDrawDragRgn();
  214.  
  215.     SetPort( me);
  216.     PenNormal();
  217.  
  218.     if( (gSetWTitleOK & needToUpdateWindowTitle) == true)
  219.     {
  220. #ifndef DEMO
  221.         SetWTitle( me, windowTitle);
  222. #endif
  223.         needToUpdateWindowTitle = false;
  224.     }
  225.     
  226.     if( randomizing == false)
  227.     {
  228.         if( gEraseWindow == true)
  229.             EraseRect( &windowRect);
  230.         
  231.         if( gQualudesUpdate == false)
  232.         {        //    This code sets CopyBits to do the right thing...
  233.             SetRect( &windowRect, windPictRect.left, 
  234.                                   windPictRect.top + worldRect.top,
  235.                                   windPictRect.left + pictWidth,
  236.                                   windPictRect.top + worldRect.bottom);
  237.         }    //    The Qualudes option tells copybits to do screwy things
  238.         
  239.         UseGWorld();
  240.         SetPort( me);
  241.  
  242.         CopyBits(    (const BitMap *) (*GetGWorldPixMap(sortGWorld)),
  243.                     (const BitMap *) (*GetGWorldPixMap((CGrafPtr) me)),
  244.                     &worldRect, &windowRect, srcCopy, (RgnHandle)0);
  245.         
  246.         UnuseGWorld();
  247.         
  248.         ValidRect( &windowRect);
  249.         
  250.         if( doneSorting == false)
  251.             //        Invert the top & bottom rect so that no drawing takes place!!
  252.             //    The sort algorithm expands this rect so that it is the smallest
  253.             //    that it needs to be to incorporate the bits modified
  254.             SetRect( ©BitsRect, 0, 0x7FFF, pictWidth, -1);
  255.         else
  256.             copyBitsRect = worldPictRect;
  257.     }
  258.     else
  259.     {
  260.         short                barWidth;
  261.         short                barHeight;
  262.         short                barLeftEdge;
  263.         short                barTopEdge;
  264.         Rect                barRect;
  265.         PixPatHandle        barPixPat = GetPixPat( 128);
  266.         
  267.         ValidRect( &windowRect);
  268.         if( pictWidth >= 100)
  269.             barWidth = 100;
  270.         else
  271.             barWidth = pictWidth - 10;
  272.         barLeftEdge =  windPictRect.left + ((pictWidth-barWidth) >> 1);
  273.         if( pictHeight >= 20)
  274.             barHeight = 12;
  275.         else
  276.             barHeight = pictHeight;
  277.         
  278.         if( pictHeight >= 100)
  279.             barTopEdge = windPictRect.top + pictHeight-60;
  280.         else
  281.             barTopEdge = windPictRect.top + ((pictHeight-barHeight) >> 1);
  282.         
  283.         
  284.         SetRect( &barRect, barLeftEdge, barTopEdge, barLeftEdge+barWidth, barTopEdge+barHeight);
  285.         InsetRect( &barRect, -1, -1);
  286.         FrameRect( &barRect);
  287.         InsetRect( &barRect, 1, 1);
  288.         barRect.right = barLeftEdge + (barWidth * percentComplete / 100);
  289.         if( barPixPat)
  290.         {
  291.             FillCRect( &barRect, (PixPatHandle) barPixPat);
  292.             DisposePixPat( barPixPat);
  293.         }
  294.         else
  295.             PaintRect( &barRect);
  296.         
  297.         //    Erase the right side of the rectangle
  298.         if( percentComplete == 5)
  299.         {
  300.             barRect.left = barRect.right+1;
  301.             barRect.right = barLeftEdge+barWidth;
  302.             EraseRect( &barRect);
  303.         }
  304.     }
  305.  
  306.     XDrawDragRgn();
  307. }
  308.  
  309.  
  310. void    GWorldObj::BackGroundObj( void)
  311. {
  312.     if( gHasThreads == true) 
  313.         YieldToThread( threadInfo);
  314.  
  315.     if( (needToUpdateWindowTitle & gSetWTitleOK) == true)
  316.         DrawObj();
  317.  
  318.     if( doneSorting == true && gContinuous == true)
  319.         if( TickCount() > (gContinuousTime * 60 + finishedTime))
  320.             MouseClickObj( (EventRecord *) 0);
  321. }    
  322.  
  323.  
  324. void    GWorldObj::IdleObj( void)
  325. {
  326.     WindowPeek           *firstWindow = (WindowPeek *) 0x9D6;        //    Start at the first window
  327.     WindowPeek            windowList = (WindowPeek) *firstWindow;    //    Walk the list
  328.     GWorldObj           *target;
  329.     short                windowCount;
  330.     
  331.     windowCount = 1;
  332.     while( windowList)
  333.     {
  334.         target = (GWorldObj *)(windowList->refCon);
  335.         if( windowCount++ == gNextBkgndWindowNum)
  336.         {
  337.             target->BackGroundObj();
  338.             ++gNextBkgndWindowNum;
  339.             return;
  340.         }
  341.         windowList = windowList->nextWindow;
  342.     }
  343.     //    If we get here we obviously have a gNextBkgndWindowNum which is > than the number
  344.     //    of open windows.  Therefore, set gNextBkgnd to 1 and send an update event to the
  345.     //    first window in the window list (if there is a first window)
  346.     gNextBkgndWindowNum = 1;
  347.     windowList = (WindowPeek) *firstWindow;
  348.     if( windowList)
  349.     {
  350.         target = (GWorldObj *)(windowList->refCon);
  351.         target->BackGroundObj();
  352.         ++gNextBkgndWindowNum;
  353.     }
  354. }
  355.  
  356.  
  357.  
  358.  
  359. /****************************************************************************/
  360. /*                                                                          */
  361. /*                              Scramble Pict                               */
  362. /*                                                                          */
  363. /****************************************************************************/
  364. void    GWorldObj::ScramblePict( void)
  365. {
  366.     long            loop;
  367.     RGBColor        pixColor = {0, 0, 0};
  368.     Byte            pixelData;
  369.     Byte           *tOffscreenPtr;
  370.     long            horiz;
  371.     long            oneTwentieth;
  372.     long            loopTwentieth;
  373.     short            percentPerPiece = 5;
  374.     long           *tickPtr = (long *)0x16A;
  375.     char            mmuMode = true32b;
  376. #ifdef    GenPictRects
  377.     FILE           *f;
  378.     short            bytesPerRow;
  379.     char            cPictName[32];
  380.     short            ci;
  381. #endif
  382.         
  383.     randomizing = true;
  384.     percentComplete = 0;
  385.     SetTitle( (const unsigned char*)"\pRandomizing");
  386.     GetPort( &savePort);
  387.  
  388.     SetPort( me);
  389.     pixColor.red = pixColor.blue = pixColor.green = 0;
  390.     DrawObj();
  391.     
  392.     HLock( (Handle)sortList);
  393.     sortListPtr = *sortList;
  394. //    if( !sortListPtr)
  395. //        DebugStr("\pScramble: sortListPtr == nil!");
  396.  
  397.     UseGWorld();
  398. //    offscreenPtr = (Byte *)GetPixBaseAddr(  sortGWorld->portPixMap);
  399. #ifdef DEMO
  400.     offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
  401.                         (**(((CWindowPtr)me)->portPixMap)).bounds.left;
  402. #endif
  403.     tOffscreenPtr = offscreenPtr;
  404.  
  405. #ifdef    GenPictRects
  406.     cPictName[ci = pictureName[0]] = '\0';
  407.     while( ci--)
  408.         cPictName[ci] = pictureName[ci+1];
  409.     f = fopen( "Sys:PictureRects", "w");
  410.     if( !f)
  411.         DebugStr( "\pERROR: File failed to open");
  412.     fprintf( f, "NuRect %s = { %d, %d, %d, %d};\n", cPictName, me->portRect.left, me->portRect.top, me->portRect.right, me->portRect.bottom);
  413.     fprintf( f, "char %s[] = {", cPictName);
  414.     bytesPerRow = 16;
  415. #endif
  416.  
  417.     horiz = 0;
  418.     SwapMMUMode( &mmuMode);        //    Switch to 32 bit mode for accessing pixels
  419.  
  420.     for( loop = 0; loop < N; ++loop)
  421.     {
  422.  
  423.         pixelData = offscreenPtr[horiz];
  424.         sortListPtr[loop] = ((long) pixelData) | loop << 8;
  425.         ++horiz;
  426.         if( horiz == pictWidth)
  427.         {
  428.             horiz = 0;
  429.             offscreenPtr += pictRowBytes;
  430.         }
  431. #ifdef GenPictRects
  432.         SwapMMUMode( &mmuMode);        //    Switch back to make stupid calls
  433.         
  434.         fprintf( f, "0x%2.2X, ", (unsigned short) pixelData);
  435.         if( !--bytesPerRow)
  436.         {
  437.             fprintf( f, "\n\t\t\t");
  438.             fflush( f);
  439.             bytesPerRow = 16;
  440.         }
  441.         SwapMMUMode( &mmuMode);        //    And switch again...
  442. #endif
  443.     }
  444.  
  445.     SwapMMUMode( &mmuMode);        //    Switch back to x mode
  446.     
  447. #ifdef GenPictRects
  448.     fprintf( f, "};\n");
  449.     fclose( f);
  450. #endif
  451.  
  452.     offscreenPtr = tOffscreenPtr;
  453.     
  454.     oneTwentieth = (N / 20) + 0;
  455.     loopTwentieth = 0;
  456.     yieldTime = TickCount() + gYieldDelay;
  457.  
  458.     SwapMMUMode( &mmuMode);        //    Switch to 32 bit mode for accessing pixels
  459.  
  460.     for( loop = N-1; loop > 1; --loop)
  461.     {
  462.         ExchangeSortItem( RandomPixel(loop), loop);
  463.         
  464.         ++loopTwentieth;
  465.  
  466.         if( loopTwentieth > oneTwentieth)
  467.         {
  468.             percentComplete += percentPerPiece;
  469.             loopTwentieth = 0;
  470.  
  471.             if( TickCount() >= yieldTime)
  472.             {
  473.                 SwapMMUMode( &mmuMode);        //    Switch back to mode X for other purposes
  474.  
  475.                 UnuseGWorld();
  476.                 SetPort( me);
  477.                 DrawObj();
  478.  
  479.                 if( yieldOnlyToMe == false)
  480.                     YieldToAnyThread();
  481.                 else
  482.                     YieldToThread( kApplicationThreadID);
  483.  
  484.                 UseGWorld();
  485.  
  486. #ifdef DEMO
  487.                 offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
  488.                                 (**(((CWindowPtr)me)->portPixMap)).bounds.left;
  489. #endif
  490.                 yieldTime = TickCount() + gYieldDelay;
  491.  
  492.                 SwapMMUMode( &mmuMode);        //    Switch into 32 bit mode, again
  493.             }
  494.         }
  495.     }
  496.     
  497.     UnuseGWorld();
  498.  
  499.     SwapMMUMode( &mmuMode);        //    And now switch back to mode X
  500.  
  501.     SetPort( me);
  502.     DrawObj();
  503.  
  504.     HUnlock( (Handle)sortList);
  505.     randomizing = false;
  506. }
  507.  
  508.  
  509.  
  510.  
  511.  
  512. /****************************************************************************/
  513. /*                                                                          */
  514. /*                        Randomization Stuff                               */
  515. /*                                                                          */
  516. /****************************************************************************/
  517. long    GWorldObj::RandomPixel( long max)        //    Return a # between 0 <= x < max
  518. {
  519.     long            randomNum = 0x7FFFFFFF;        //    The ultimate long
  520.     long            tempN;
  521.     short            numNBits;
  522.     short            numShiftBits, numRandomBits;
  523.     
  524. //    Random Number Initialization
  525.     tempN = max;
  526.     numNBits = 1;                // Using the additive conguential method (Random numbers)
  527.     while (tempN >>= 1)            // Count the number of bits required to hold N    
  528.         ++numNBits;                //    example:  to hold 0x37 requires 6 bits (0-3F)
  529.  
  530.     numRandomBits = 31;    
  531.     numShiftBits = numRandomBits - numNBits;
  532.     
  533.     while( randomNum >= max)
  534.     {
  535. //        RandomNum generator
  536.         randomNum = randomSeed = (randomSeed & 1) ^ ((randomSeed & (1L << 28)) >> 28)
  537.                                ? (randomSeed >> 1) : (randomSeed >> 1) | 0x40000000;
  538. //        This next line "mixes" some of the upper bits with the lower bits
  539.         randomNum = (randomNum >> numShiftBits) ^ (randomNum & (0x7FFFFFFF >> numShiftBits));
  540.     }
  541.     
  542.     return randomNum;    
  543. }
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554. /****************************************************************************/
  555. /*                                                                          */
  556. /*                           Dumb Application                               */
  557. /*                                                                          */
  558. /****************************************************************************/
  559.  
  560. short        GWorldObj::gSortSize;
  561. Boolean        GWorldObj::gEraseWindow;
  562. Boolean        GWorldObj::gHasThreads;
  563. Boolean        GWorldObj::gQualudesUpdate;
  564. Boolean        GWorldObj::gContinuous;
  565. short        GWorldObj::gContinuousTime;
  566. Boolean        GWorldObj::gSaveWindowPositions;
  567. short        GWorldObj::gYieldDelay;
  568. short        GWorldObj::gNumPictures;
  569. MenuHandle    GWorldObj::gPicturesMenu;
  570. short        GWorldObj::gWindOffSet;
  571. short        GWorldObj::gNextBkgndWindowNum;
  572. short        GWorldObj::gSortAlgorithm;
  573.  
  574. void    GWorldObj::InitObj( void)
  575. {
  576.     long    threadsPresentBit;
  577.     
  578. //    inherited::InitObj();        // This DOESN'T WORK IN MPW C++ ????
  579.     
  580.     isColor = gMac.hasColorQD;        // Retain the color bit
  581.     useActivateClicks = false;        // Do not interpret activate events as action events
  582.  
  583. //    Set GWorldObj specific global variables
  584.     gEraseWindow = false;
  585.     gYieldDelay = 6;
  586.     gSortSize = 0;
  587.     gWindOffSet = 0;
  588. #ifdef DEMO
  589.     gSetWTitleOK = false;
  590. #else
  591.     gSetWTitleOK = true;
  592. #endif
  593.     gDragRgnHandle = (RgnHandle) 0;
  594.     gDragRgnHandleValid = false;
  595.     gQualudesUpdate = false;
  596.     gContinuous = true;
  597.     gContinuousTime = 0;
  598.     gSaveWindowPositions = false;
  599.     gNextBkgndWindowNum = 1;
  600.     gSortAlgorithm = iRandomSort;    //    default is a Random sort
  601.     
  602.     if( Gestalt( gestaltThreadMgrAttr, &threadsPresentBit) == noErr)
  603.         gHasThreads = (1<<gestaltThreadMgrPresent) & threadsPresentBit ? true : false;
  604.     
  605. //    Build the Pictures Menu #PICTURESMENU
  606.     gPicturesMenu = NewMenu( PICTURESMENU, (const unsigned char*)"\pPictures");
  607.     AddResMenu( gPicturesMenu, 'PICT');
  608.     InsertMenu( gPicturesMenu, -1);
  609.  
  610. //    Count the number of Pictures in the menu
  611.     gNumPictures = CountMItems( gPicturesMenu);
  612.     
  613.     if( gHasThreads)
  614.     {
  615.         long               *DragHook = (long *)0x09F6;        // DragHook is called during DragWindow, etc.
  616.         Handle                startupPictStrHandle;
  617.  
  618. #ifndef __powerc
  619.         *DragHook = (long) DragHookForThreads;        //    Patch DragHook
  620. #endif
  621.  
  622.         startupPictStrHandle = GetNamedResource( 'STR#', (const unsigned char*)"\pStartup Pictures");
  623.         if( startupPictStrHandle)    // If there is a predefined list of startup pictures
  624.         {                            //    Load them in now
  625.             short                startupPictID;
  626.             ResType                tempType;
  627.             Str255                tempName;
  628.             Boolean                newWindow = true;
  629.             short                windowCount = 1;
  630.             GWorldObj           *newObj;
  631.             
  632.             GetResInfo( startupPictStrHandle, &startupPictID, &tempType, tempName);
  633.             while( newWindow == true)
  634.             {
  635.                 newWindow = false;            //    Unless this window works, stop making them
  636.                 newObj = new GWorldObj;
  637.                 if( newObj)
  638.                 {
  639.                     GetIndString( newObj->pictureName, startupPictID, windowCount);
  640.                     if( newObj->pictureName[0])
  641.                     {
  642.                         newWindow = newObj->NewWindowObj();    // did this window work?
  643.                     }
  644.                     ++windowCount;
  645.                     YieldToAnyThread();
  646.                 }
  647.             }
  648.             
  649.         }
  650.         else        //    If there is no predefined list of pictures, 
  651.         {            //    just load in consecutive ones
  652.             GWorldObj           *a;
  653.             Boolean                newWindow = false;
  654.             short                windowCount;
  655.  
  656.             windowCount = 1;
  657.             while( newWindow == true)
  658.             {
  659.                 a = new GWorldObj;
  660.                 if( a)
  661.                 {
  662.                     GetItem( gPicturesMenu, windowCount, a->pictureName);
  663.                     newWindow = a->NewWindowObj();
  664.                     YieldToAnyThread();
  665.     //    RST:  The following fix will force only one window to be created!
  666.                     newWindow = false;
  667.                 }
  668.                 ++windowCount;
  669.             }
  670.         }
  671.     }
  672.     else        //    gHasThreads == NOT!!
  673.     {
  674.         GWorldObj           *a;
  675.  
  676.         a = new GWorldObj;
  677.         if( a)
  678.         {
  679.  
  680.             GetItem( gPicturesMenu, 1, a->pictureName);
  681.             a->NewWindowObj();
  682.         }
  683.     }
  684. }
  685.  
  686. Boolean    GWorldObj::PrepareGWorld( void)
  687. {
  688.     Rect            worldRect;
  689.     OSErr            myOSErr;
  690.     GWorldPtr        myGWorld;
  691.     GDHandle        oldGDevice;
  692.     CGrafPtr        oldGWorld;
  693.  
  694. //    if( aboutBox)
  695. //        return true;
  696.     
  697.     sortPict = (PicHandle)GetNamedResource( 'PICT', pictureName);
  698.     
  699.     if( sortPict == nil)
  700.         return false;
  701.     
  702.     randomizing = true;
  703.     percentComplete = 0;
  704.     doneSorting = false;
  705.     yieldOnlyToMe = false;
  706.     
  707.     worldPictRect = (*sortPict)->picFrame;
  708.     pictWidth = worldPictRect.right - worldPictRect.left;
  709.     pictHeight = worldPictRect.bottom - worldPictRect.top;
  710.     
  711.     SetRect(   &worldPictRect, 0, 0, pictWidth, pictHeight);
  712.     copyBitsRect = worldPictRect;
  713.     windPictRect = worldPictRect;
  714.     worldRect = worldPictRect;
  715.  
  716. #ifdef DEMO
  717.     if( !me)
  718.     {
  719.         ReleaseResource( (Handle)sortPict);
  720.         return true;
  721.     }
  722. #endif
  723.     
  724.     GetGWorld( &oldGWorld, &oldGDevice);
  725.     
  726.     myOSErr = NewGWorld( &myGWorld, 8, &worldRect, (CTabHandle) 0, (GDHandle)0, 0);
  727.     
  728.     if( myOSErr != noErr)
  729.     {
  730.         ReleaseResource( (Handle)sortPict);
  731.         return false;
  732.     }
  733.     
  734.     LockPixels( GetGWorldPixMap( myGWorld));
  735.             
  736. #ifdef DEMO
  737.     sortGWorld = (GWorldPtr) me;
  738. #else
  739.     sortGWorld = myGWorld;
  740. #endif
  741.     
  742. //    f->osPixmap = ((CWindowPtr)me)->portPixMap;
  743. //    f->pixels = (unsigned char *) GetPixBaseAddr( f->osPixmap);
  744. //    f->osRowBytes = (**(f->osPixmap)).rowBytes & 0x3FFF;
  745. //    f->pixels -= (long) ((**(f->osPixmap)).bounds.top * f->osRowBytes) + (**(f->osPixmap)).bounds.left;
  746.  
  747. #ifdef DEMO
  748.     pictRowBytes = 832;
  749. #else
  750.     pictRowBytes = (*GetGWorldPixMap( sortGWorld))->rowBytes & 0x3FFF;
  751. #endif
  752.     sortListSize = (long) pictWidth * (long) pictHeight ;
  753.     
  754.     sortList = (long **) NewHandle( sortListSize * sizeof(long) );
  755.                 
  756.     if( sortList == nil)
  757.     {
  758.         ReleaseResource( (Handle)sortPict);
  759.         DisposeGWorld( myGWorld);
  760.         return false;
  761.     }
  762.     
  763. #ifdef DEMO
  764.     GetGWorld( &oldGWorld, &oldGDevice);
  765.     SetPort( (GrafPort*)sortGWorld);
  766. #else
  767. //    GetGWorld( &oldGWorld, &oldGDevice);
  768. //    SetGWorld( sortGWorld, nil);
  769.     UseGWorld();
  770. #endif
  771.     
  772.     EraseRect( &worldRect);
  773.     DrawPicture( sortPict, &worldRect);
  774.     
  775.     ReleaseResource( (Handle)sortPict);
  776.  
  777. //    SetGWorld( oldGWorld, oldGDevice);
  778.     UnuseGWorld();
  779.     
  780.     return true;            //    YES!! The everything worked out!
  781. }
  782.  
  783. Boolean    GWorldObj::NewWindowObj( void)
  784. {
  785.     Rect        winRect;
  786.     Handle        winRectHandle;
  787.     Point        midPoint;
  788.     
  789.     me = nil;
  790.     sortGWorld = nil;
  791.     needToUpdateWindowTitle = false;
  792.     windowTitle[0] = '\0';
  793.     savedCount = 0;
  794.     
  795.     aboutBox = false;
  796.     
  797.     if( PrepareGWorld() == true)
  798.     {
  799.         windPictRect = worldPictRect;
  800.         winRect = windPictRect;
  801.         sortAlgorithm = gSortAlgorithm;
  802.         randomSeed = TickCount();
  803.         yieldTime = 0;
  804.         
  805.         OffsetRect( &winRect, 40 + gWindOffSet, 40 + gWindOffSet);
  806.         gWindOffSet += 40;
  807.         if( gWindOffSet >= 300)
  808.             gWindOffSet = 0;
  809.         
  810.         winRectHandle = GetNamedResource( 'RECT', pictureName);
  811.         if( winRectHandle)
  812.         {
  813.             winRect = **((Rect**)winRectHandle);
  814.             ReleaseResource( winRectHandle);
  815.         }
  816.         
  817.         midPoint.h = winRect.left + ((winRect.right - winRect.left)>>1);
  818.         midPoint.v = winRect.top + ((winRect.bottom - winRect.top)>>1);
  819. #ifdef __CONDITIONALMACROS__
  820.         if( !PtInRgn( midPoint, LMGetGrayRgn()))
  821. #else
  822.         if( !PtInRgn( midPoint, *(RgnHandle *)GrayRgn))
  823. #endif
  824.         {
  825.             DebugStr( (const unsigned char*)"\pWindow's not on the screen!!\n");
  826.         }
  827.  
  828.         me = NewCWindow( NIL, &winRect, (ConstStr255Param)"\pLoading", true, noGrowDocProc, (WindowPtr)-1, true, 
  829.             /* CRITICALLY IMPORTANT:: */   (long) this);
  830.         
  831.         if( winRectHandle)
  832.             ReleaseResource( winRectHandle);
  833.         
  834.         if( me)        /* Do these things if the window was created ! */
  835.         {
  836.             ((WindowPeek)me)->windowKind = WindowObjKind;
  837.  
  838.             if( !sortGWorld)
  839.                 PrepareGWorld();
  840.  
  841.             if( BeginNewThread() == true)
  842.             {
  843.                 return true;
  844.             }
  845.             DisposeWindow( me);
  846.             DisposeGWorld( sortGWorld);
  847.             DisposeHandle( (Handle)sortList);
  848.             return false;
  849.         }
  850.         else            //  me == nil        
  851.             return false;
  852.     }
  853.     else
  854.         return false;
  855. }
  856.  
  857.  
  858. Boolean    GWorldObj::AboutObj( void)
  859. {
  860.     char      **pictName = (char **)GetResource( 'STR ', ABOUTPICTURENAMEID);
  861.     short        loop;
  862.     short        itemType;
  863.     Handle        itemHandle;
  864.     Rect        itemRect;
  865.     short        itemHit;
  866.     
  867.     sortGWorld = nil;
  868.     needToUpdateWindowTitle = false;
  869.     windowTitle[0] = '\0';
  870.     savedCount = 0;
  871.  
  872.     if( pictName)
  873.     {
  874.         //    Copy the picture name string from the Handle to this->pictureName
  875.         for( loop = pictureName[0] = (*pictName)[0]; loop ; --loop)
  876.             pictureName[loop] = (*pictName)[loop]; 
  877.         
  878.         ReleaseResource( (Handle)pictName);
  879.         
  880.         aboutBox = true;
  881.         me = nil;
  882.         
  883.         if( PrepareGWorld() == true)
  884.         {
  885.             me = (WindowPtr) GetNewDialog( ABOUTDIALOG, (Ptr) 0, (WindowPtr) -1);
  886.             if( me)
  887.             {
  888.                 ((WindowPeek)me)->refCon = (long)this;
  889.                 GetDItem( (DialogPtr) me, ABOUTDIALOGPICT, &itemType, &itemHandle, &itemRect);
  890.                 windPictRect = itemRect;
  891.                 
  892.                 if( gHasThreads)
  893.                 {
  894.                     if( BeginNewThread() == true)
  895.                     {
  896. #ifdef __powerc
  897.                         AboutBoxFilterUPP = NewModalFilterProc( (long (*)(void))AboutBoxFilter);
  898. #endif            
  899.                         itemHit = -1;
  900.                         while( itemHit != 1)
  901.                         {
  902. #ifdef __powerc
  903.                             ModalDialog( AboutBoxFilterUPP, &itemHit);
  904. #else
  905.                             ModalDialog( AboutBoxFilter, &itemHit);
  906. #endif
  907.                         }
  908.                         
  909.                         if( threadInfo != 0)
  910.                             DisposeThread( threadInfo, 0, false);
  911. #ifdef __powerc
  912.                         if( AboutBoxFilterUPP)
  913.                             DisposePtr( (Ptr) AboutBoxFilterUPP);
  914. #endif
  915.                     }
  916.                 }
  917.                 else
  918.                 {
  919.                     itemHit = -1;
  920.                     
  921.                     //    First, allow the redraw algorithm to kick in
  922.                     for( loop = 0; loop < 3 && itemHit == -1; loop ++)
  923. #ifdef __powerc
  924.                         ModalDialog( (class RoutineDescriptor*)0, &itemHit);
  925. #else
  926.                         ModalDialog( (ModalFilterProcPtr)0, &itemHit);
  927. #endif
  928.  
  929.                     //    Randomize and Sort the picture
  930.                     if( itemHit == -1)
  931.                         BeginNewThread();
  932.                     
  933.                     //    Now wait for the user to quit this dialog
  934.                     while( itemHit != 1)
  935. #ifdef __powerc
  936.                         ModalDialog( (class RoutineDescriptor*)0, &itemHit);
  937. #else
  938.                         ModalDialog( (ModalFilterProcPtr)0, &itemHit);
  939. #endif
  940.                 }
  941.     
  942.                 DisposeDialog( (DialogPtr) me);
  943.                 me = (WindowPtr)0;
  944.             }
  945.     
  946.             DisposeHandle( (Handle)sortList);
  947.             DisposeGWorld( sortGWorld);
  948.             return false;
  949.         }
  950.         else
  951.         {
  952.             return false;
  953.         }
  954.     }
  955.     return false;
  956. }
  957.  
  958. pascal Boolean    AboutBoxFilter( DialogPtr dialog, EventRecord *event, short *itemHit)
  959. {
  960.     GWorldObj           *object = (GWorldObj *)((WindowPeek)dialog)->refCon;
  961.     GWorldObj           *target;
  962.     WindowPtr            whichWindow;
  963.     short                windowPart;
  964.     
  965.     if( (event->what == keyDown) && 
  966.        ( ((event->message & charCodeMask) == 13) ||     //    Test for RETURN key
  967.          ((event->message & charCodeMask) == 3 ) ) )    //    Test for ENTER key
  968.     {
  969.         *itemHit = 1;
  970.         return true;
  971.     }
  972.     
  973.     if( event->what == mouseDown)
  974.     {
  975.         windowPart = FindWindow( event->where, &whichWindow);
  976.         if( whichWindow == object->me && windowPart == inDrag)
  977.         {
  978.             object->DragWindowObj( event);
  979.             return true;
  980.         }
  981.     }
  982.  
  983.     if( event->what == updateEvt)
  984.     {
  985.         target = (GWorldObj *)((WindowPeek)event->message)->refCon;
  986.  
  987.         target->UpdateObj();
  988.         if( target == object)
  989.             return false;
  990.         return true;
  991.     }
  992.  
  993.     if( event->what == nullEvent)
  994.         object->IdleObj();
  995.  
  996.     return false;
  997. }
  998.  
  999.  
  1000.  
  1001. void    GWorldObj::AdjustMenusObj( void)
  1002. {
  1003.     Str255                yieldDelayStr;
  1004.     Str255                yieldDelayMenuStr;
  1005.     MenuHandle            userOptionsMenu = GetMHandle( USEROPTIONSMENU);
  1006.     MenuHandle            sortAlgorithmMenu = GetMHandle( mSortAlgorithm);
  1007.     short                yieldDMLen, numStrLen;
  1008.     MenuHandle    menu;
  1009.  
  1010.     menu = GetMHandle( mFile);            // Do the File menu first
  1011.     if( menu)
  1012.     {
  1013.         EnableItem(menu, iNew);                // Enable the items, one at a time...
  1014.         EnableItem(menu, iOpen);
  1015.         if( me != NIL)
  1016.         {
  1017.             EnableItem(menu, iClose);
  1018.         }
  1019.         else
  1020.         {
  1021.             DisableItem(menu, iClose);
  1022.         }
  1023.     
  1024.         DisableItem(menu, iSave);
  1025.         DisableItem(menu, iSaveAs);
  1026.         DisableItem(menu, iRevert);
  1027.         DisableItem(menu, iPageSetup);
  1028.         DisableItem(menu, iPrint);
  1029.         EnableItem(menu, iQuit);
  1030.     }
  1031.     
  1032.     menu = GetMHandle( mEdit);
  1033.     if( menu)
  1034.     {
  1035.         DisableItem(menu, iUndo);
  1036.         DisableItem(menu, iCut);
  1037.         DisableItem(menu, iCopy);
  1038.         DisableItem(menu, iClear);
  1039.         DisableItem(menu, iPaste);
  1040.     }
  1041.  
  1042.     if( userOptionsMenu)
  1043.     {
  1044.         NumToString( gYieldDelay, yieldDelayStr);
  1045.         GetItem( userOptionsMenu, UO_SHOWTTYDELAY, yieldDelayMenuStr);
  1046.         yieldDMLen = yieldDelayMenuStr[0];
  1047.         while( yieldDelayMenuStr[yieldDMLen] != ' ')
  1048.             yieldDMLen--;
  1049.         
  1050.         numStrLen = yieldDelayStr[0];
  1051.         yieldDelayMenuStr[0] = yieldDMLen + numStrLen;
  1052.         while( numStrLen)
  1053.         {
  1054.             yieldDelayMenuStr[yieldDMLen + numStrLen] = yieldDelayStr[numStrLen];
  1055.             numStrLen--;
  1056.         }
  1057.         SetItem( userOptionsMenu, UO_SHOWTTYDELAY, yieldDelayMenuStr);
  1058.         CheckItem( userOptionsMenu, UO_ERASE, gEraseWindow);
  1059.         CheckItem( userOptionsMenu, UO_QUALUDES, gQualudesUpdate);
  1060.         CheckItem( userOptionsMenu, UO_CONTINUOUS5Sec, gContinuous && (gContinuousTime == 5));
  1061.         CheckItem( userOptionsMenu, UO_CONTINUOUS0Sec, gContinuous && (gContinuousTime == 0));
  1062.         CheckItem( userOptionsMenu, UO_SAVEWINDPOS, gSaveWindowPositions);
  1063.         CheckItem( userOptionsMenu, UO_SORT_0, gSortSize == 0);
  1064.         CheckItem( userOptionsMenu, UO_SORT_1, gSortSize == 1);
  1065.     }
  1066.  
  1067.     if( sortAlgorithmMenu)
  1068.     {
  1069.         CheckItem( sortAlgorithmMenu, iShellSort, gSortAlgorithm == iShellSort);
  1070.         CheckItem( sortAlgorithmMenu, iHeapSort , gSortAlgorithm == iHeapSort );
  1071.         CheckItem( sortAlgorithmMenu, iQuickSort , gSortAlgorithm == iQuickSort );
  1072.         CheckItem( sortAlgorithmMenu, iRandomSort , gSortAlgorithm == iRandomSort );
  1073.     }
  1074. }
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080. void    GWorldObj::MenuObj( short menuID, short menuItem, EventRecord *event)
  1081. {
  1082.     WINDOWOBJ       *a;
  1083.     Str255            daName;
  1084.     
  1085.     switch( menuID )
  1086.     {
  1087.         case mApple:
  1088.             if( menuItem == iAbout)
  1089.             {
  1090.                 WINDOWOBJ           *a;
  1091.                 a = new WINDOWOBJ;
  1092.                 if( a)
  1093.                 {
  1094.                     a->AboutObj();
  1095.                     delete a;
  1096.                 }
  1097.             }
  1098.             else        //    Open a desk accessory...
  1099.             {
  1100.                 GetItem(GetMHandle(mApple), menuItem, daName);
  1101.                 (void) OpenDeskAcc(daName);
  1102.             }
  1103.             break;
  1104.         case mFile:
  1105.             switch( menuItem)
  1106.             {
  1107.                 case iClose:
  1108.                     CloseWindowObj();
  1109.                     break;
  1110.                 case iPageSetup:
  1111.                     PageSetupObj();
  1112.                     break;
  1113.                 case iPrint:
  1114.                     PrintObj();
  1115.                     break;
  1116.                 default:
  1117.                     AppMenu( menuID, menuItem);        // This is like inheritance!!
  1118.                     break;
  1119.             }
  1120.             break;
  1121.  
  1122.         case USEROPTIONSMENU:
  1123.             switch( menuItem)
  1124.             {
  1125.                 case UO_ERASE:        //    Erase Window User Option
  1126.                     gEraseWindow = !gEraseWindow;
  1127.                     break;
  1128.                 case UO_QUALUDES:    //    Alter the CopyBits behavior
  1129.                     gQualudesUpdate = !gQualudesUpdate;
  1130.                     break;
  1131.                 case UO_CONTINUOUS5Sec:    //    Run for ever
  1132.                 case UO_CONTINUOUS0Sec: //    Run for ever, fast!
  1133.                     if( gContinuous)
  1134.                         gContinuous = (gContinuousTime == 5 && menuItem == UO_CONTINUOUS5Sec) ||
  1135.                                       (gContinuousTime == 0 && menuItem == UO_CONTINUOUS0Sec)
  1136.                                             ? false : true;
  1137.                     else
  1138.                         gContinuous = true;
  1139.                     gContinuousTime = (UO_CONTINUOUS5Sec == menuItem) ? 5 : 0;
  1140.                     break;
  1141.                 case UO_SAVEWINDPOS://    Run for ever
  1142.                     gSaveWindowPositions = !gSaveWindowPositions;
  1143.                     break;
  1144.                 case UO_SORT_0:        //    Complete the Sort 100%
  1145.                     gSortSize = 0;
  1146.                     break;
  1147.                 case UO_SORT_1:        //    Finish 1 step before the sort is complete
  1148.                     gSortSize = 1;
  1149.                     break;
  1150.                 case UO_BLANK:        //    This is a dividing line
  1151.                     break;
  1152.                 case UO_SHOWTTYDELAY:        //    This displays the Time To Yield
  1153.                     break;
  1154.                 case UO_DECREASETTY:        //    Decrease Time To Yield Delay
  1155.                     if( gYieldDelay > 5)
  1156.                         gYieldDelay -= 4;
  1157.                     break;
  1158.                 case UO_INCREASETTY:        //    Increase Time To Yield Delay
  1159.                     gYieldDelay += 4;
  1160.                     break;
  1161.             }
  1162.             break;
  1163.  
  1164.         case PICTURESMENU:
  1165.             a = new WINDOWOBJ;
  1166.             if( a)
  1167.             {
  1168.                 GetItem( gPicturesMenu, menuItem, a->pictureName);
  1169.                 if( a->NewWindowObj() == false)
  1170.                     delete a;
  1171.             }
  1172.             break;
  1173.             
  1174.         case mSortAlgorithm:
  1175.             gSortAlgorithm = menuItem;
  1176.             break;
  1177.         
  1178.         default:
  1179.             if( (event->message & charCodeMask) == 'n')
  1180.             {
  1181.                 WINDOWOBJ           *a;
  1182.                 a = new WINDOWOBJ;
  1183.                 if( a)
  1184.                 {
  1185.                     MenuHandle    gPicturesMenu = GetMHandle( PICTURESMENU);
  1186.                     
  1187.                     if( gPicturesMenu)
  1188.                     {
  1189.                         GetItem( gPicturesMenu, (short)(((short)(TickCount()) & 0x7FFF) % a->gNumPictures), a->pictureName);
  1190.                         if( a->NewWindowObj() == false)
  1191.                             delete a;
  1192.                     }
  1193.                 }
  1194.             }
  1195.             else if( ((event->message & charCodeMask) == ',') || 
  1196.                      ((event->message & charCodeMask) == '<') )
  1197.             {
  1198.                             if( a->gYieldDelay > 5)
  1199.                                     a->gYieldDelay -= 4;
  1200.             }
  1201.             else if( ((event->message & charCodeMask) == '.') || 
  1202.                      ((event->message & charCodeMask) == '>') )
  1203.                             gYieldDelay += 4;
  1204.             else if( ((event->message & charCodeMask) >= '1') && 
  1205.                      ((event->message & charCodeMask) <= '0') )
  1206.             {
  1207.                             WINDOWOBJ           *a;
  1208.                             a = new WINDOWOBJ;
  1209.                             if( a)
  1210.                             {
  1211.                                 MenuHandle    gPicturesMenu = GetMHandle( PICTURESMENU);
  1212.                                 
  1213.                                 if( gPicturesMenu)
  1214.                                 {
  1215.                                     GetItem( gPicturesMenu, (short)(event->message & charCodeMask) - '0', a->pictureName);
  1216.                                     if( a->NewWindowObj() == false)
  1217.                                         delete a;
  1218.                                 }
  1219.                             }
  1220.             }
  1221.             else
  1222.                 AppMenu( menuID, menuItem);                // This is like inheritance!!
  1223.             break;
  1224.     }
  1225.     HiliteMenu(0);
  1226. }
  1227.  
  1228.  
  1229.  
  1230.  
  1231. void    GWorldObj::GrowWindowObj( EventRecord *event)
  1232. {
  1233.     //        This window doesn't grow...
  1234.     int            a = 0;
  1235.     if( a != 0)
  1236.         event->modifiers = 0;
  1237. }
  1238.  
  1239. void    GWorldObj::MouseClickObj( EventRecord *event)
  1240. {
  1241.     Rect            worldRect, windRect;
  1242.     EventRecord       *cpEvent = event;        //    Gets CFront off my back!
  1243.  
  1244.     if( doneSorting == true)
  1245.     {
  1246.         randomizing = true;
  1247.         percentComplete = 0;
  1248.         doneSorting = false;
  1249.  
  1250.         sortPict = (PicHandle)GetNamedResource( 'PICT', pictureName);
  1251.         
  1252.         if( sortPict)
  1253.         {
  1254. #ifndef DEMO
  1255.             SetPort( me);
  1256.             worldRect = worldPictRect;
  1257.             windRect = windPictRect;
  1258.             EraseRect( &windRect);
  1259.  
  1260. //            GetGWorld( &oldGWorld, &oldGDevice);
  1261. //            SetGWorld( sortGWorld, (GDHandle)0);
  1262.             UseGWorld();
  1263.  
  1264.             EraseRect( &worldRect);
  1265.             DrawPicture( sortPict, &worldRect);
  1266.             
  1267.             ReleaseResource( (Handle)sortPict);
  1268.     
  1269.             UnuseGWorld();
  1270. //            SetGWorld( oldGWorld, oldGDevice);
  1271. #endif
  1272.             BeginNewThread();
  1273.         }
  1274.     }
  1275.     else
  1276.     {
  1277.         Str255            oldWindowTitle;
  1278.         Str255            tempTitle;
  1279.         Str255            turboTitle = "\pTurbo";
  1280.         Boolean            equal;
  1281.         short            loop;
  1282.         
  1283.         GetWTitle( me, oldWindowTitle);
  1284.         SetTitle( turboTitle);
  1285.         yieldOnlyToMe = true;
  1286.         
  1287.         while( StillDown() && (doneSorting == false))
  1288.         {
  1289.             YieldToThread( threadInfo);
  1290.             GetWTitle( me, tempTitle);
  1291.             equal = true;
  1292.             for( loop = 0; (loop <= tempTitle[0]) && (equal == true); ++loop)
  1293.                 equal = (tempTitle[loop] == turboTitle[loop]);
  1294.             if( equal == false)
  1295.             {
  1296.                     GetWTitle( me, oldWindowTitle);
  1297.                     SetTitle( turboTitle);
  1298.             }
  1299.         }
  1300.             
  1301.         yieldOnlyToMe = false;
  1302.         SetTitle( oldWindowTitle);
  1303.     }
  1304. }
  1305.  
  1306. Boolean    GWorldObj::CloseWindowObj( void)
  1307. {
  1308.     if( me == FrontWindow())
  1309.     {
  1310.         if( gHasThreads && threadInfo != 0)
  1311.             DisposeThread( threadInfo, 0, false);
  1312.         DisposeHandle( (Handle)sortList);
  1313.         DisposeGWorld( sortGWorld);
  1314.         DisposeWindow( me);                    //  Call the Mac to eliminate the window!
  1315.  
  1316.         return true;
  1317.     }
  1318.     else
  1319.         return false;
  1320.         
  1321. }
  1322.  
  1323. void    GWorldObj::DrawGrowIconObj( void)
  1324. {
  1325.     //    Don't draw the grow thing!
  1326. }
  1327.  
  1328.  
  1329. void    GWorldObj::DragWindowObj( EventRecord *event)
  1330. {
  1331.     Rect            globalWindRect;            //    global as in desk top, not program wise
  1332.     Point           *tempPoint;
  1333.     Handle            rsrcRect;
  1334.     GrafPtr            savedPort;
  1335.     
  1336.     gDragRgnHandleValid = true;
  1337.     
  1338.     WindowObj::DragWindowObj( event);
  1339.     
  1340.     gDragRgnHandleValid = false;
  1341.     
  1342.     if( gSaveWindowPositions == true)
  1343.     {
  1344.     //    Create a RECT within the Actual application which is the RECT of the Window's
  1345.     //    Global portRect.  OK?  But remove this code before it ships (because it's sick
  1346.     //    to ship code which modifies its own file!!).
  1347.         
  1348.         GetPort( &savedPort);
  1349.         SetPort( me);
  1350.         
  1351.         globalWindRect = me->portRect;
  1352.         tempPoint = (Point *)&globalWindRect;
  1353.         LocalToGlobal( tempPoint);
  1354.         globalWindRect.right += globalWindRect.left;
  1355.         globalWindRect.bottom += globalWindRect.top;
  1356.         
  1357.         rsrcRect = GetNamedResource( 'RECT', pictureName);
  1358.         if( rsrcRect)
  1359.         {
  1360.             HLock( rsrcRect);
  1361.             **((Rect **) rsrcRect) = globalWindRect;
  1362.             HUnlock( rsrcRect);
  1363.             ChangedResource( rsrcRect);
  1364.         }
  1365.         else        //    resource didn't load in
  1366.         {
  1367.             rsrcRect = NewHandle( sizeof(Rect));        //    8 bytes
  1368.             if( rsrcRect)
  1369.             {
  1370.                 HLock( rsrcRect);
  1371.                 **((Rect **) rsrcRect) = globalWindRect;
  1372.                 HUnlock( rsrcRect);
  1373.                 AddResource( rsrcRect, 'RECT', UniqueID( 'RECT'), pictureName);
  1374.             }
  1375.         }
  1376.         SetPort( savedPort);
  1377.     }
  1378. }
  1379.  
  1380.  
  1381. /*
  1382.  *
  1383.  *    This code is 68K specific ...
  1384.  */
  1385.  
  1386. #ifndef __powerc
  1387.  
  1388. pascal void DragHookForThreads( void)
  1389. {
  1390.     gDragRgnHandle = ReturnA3();
  1391.     
  1392.     GetPenState( &gDragPen);
  1393.     GetPort( &gDragPort);
  1394.     gSetWTitleOK = false;
  1395.     
  1396.     YieldToAnyThread();
  1397.  
  1398.     gDragRgnHandle = (RgnHandle) 0;
  1399. #ifndef DEMO
  1400.     gSetWTitleOK = true;
  1401. #endif
  1402.     SetPort( gDragPort);
  1403.     SetPenState( &gDragPen);
  1404. }
  1405.  
  1406. pascal void    XDrawDragRgn( void)
  1407. {
  1408.     GrafPtr            savedPort;
  1409.     PenState        savedPen;
  1410.     short          **firstRgnWord;
  1411.     
  1412.     if( gDragRgnHandle  &&  gDragRgnHandleValid)
  1413.     {
  1414.         GetPenState( &savedPen);
  1415.         GetPort( &savedPort);
  1416.         
  1417.         SetPort( gDragPort);
  1418.         SetPenState( &gDragPen);
  1419.         
  1420.         firstRgnWord = (short **)gDragRgnHandle;
  1421.         if( **firstRgnWord == 0x000A)
  1422.             FrameRect( (Rect *) &((*firstRgnWord)[1]));
  1423.         else
  1424.             PaintRgn( gDragRgnHandle);
  1425.  
  1426.         SetPort( savedPort);
  1427.         SetPenState( &savedPen);
  1428.     }
  1429. }
  1430.  
  1431. #else
  1432.  
  1433. /*
  1434.  *    This code is PowerPC filler ...
  1435.  */
  1436.  
  1437. pascal void DragHoodForThreads( void)
  1438. {
  1439.     //    empty PowerPC routines
  1440. }
  1441.  
  1442. pascal void XDrawDragRgn( void)
  1443. {
  1444.  
  1445. }
  1446.  
  1447. #endif
  1448. void    GWorldObj::SetTitle( ConstStr255Param title)
  1449. {
  1450.     short            loop;
  1451.     
  1452.     if( gSetWTitleOK == true)
  1453.     {
  1454. #ifndef DEMO
  1455.         SetWTitle( me, title);
  1456. #endif
  1457.         needToUpdateWindowTitle = false;
  1458.     }
  1459.     else
  1460.         needToUpdateWindowTitle = true;
  1461.     
  1462.     loop = windowTitle[0] = title[0];
  1463.     while( loop)
  1464.     {
  1465.         windowTitle[loop] = title[loop];
  1466.         --loop;
  1467.     }
  1468. }
  1469.  
  1470.  
  1471. void    GWorldObj::UseGWorld( void)
  1472. {
  1473.     PixMapHandle        offscreenPixMapHndl;
  1474.     
  1475.     if( !savedCount++)
  1476.     {
  1477.         GetGWorld( &savedPort, &savedGDH);
  1478.         
  1479.         offscreenPixMapHndl = GetGWorldPixMap( sortGWorld);
  1480.         
  1481.         LockPixels( offscreenPixMapHndl);
  1482.     
  1483.         offscreenPtr = (Byte *) GetPixBaseAddr( offscreenPixMapHndl);
  1484.         
  1485.         SetGWorld( sortGWorld, (GDHandle) 0);
  1486.     }
  1487. }
  1488.  
  1489. void    GWorldObj::UnuseGWorld( void)
  1490. {
  1491.     PixMapHandle        offscreenPixMapHndl;
  1492.     
  1493.     if( !--savedCount)
  1494.     {
  1495.         offscreenPixMapHndl = GetGWorldPixMap( sortGWorld);
  1496.         
  1497. //        UnlockPixels( offscreenPixMapHndl);
  1498.             
  1499.         offscreenPtr = (Byte *) -1;
  1500.         
  1501.         SetGWorld( savedPort, savedGDH);
  1502.     }
  1503. }
  1504.  
  1505.